import requests
import json
from pydub import AudioSegment
import warnings


def download_bilibili_wav(bv_id, output_path):
    warnings.filterwarnings("ignore", category=UserWarning)

    # 关键请求头配置
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
        'Referer': f'https://www.bilibili.com/video/{bv_id}',
        'Cookie': 'SESSDATA=YOUR_SESSDATA; bili_jct=YOUR_BILI_JCT;'  # 必须填写有效Cookie
    }

    # 第一步：获取视频CID
    info_api = f"https://api.bilibili.com/x/web-interface/view?bvid={bv_id}"
    info_resp = requests.get(info_api, headers=headers)

    if info_resp.status_code != 200:
        print(f"视频信息请求失败: {info_resp.status_code}")
        return

    try:
        cid = info_resp.json()['data']['cid']
    except KeyError:
        print("无法获取视频CID，请检查：\n1. Cookie有效性\n2. 视频可用性")
        return

    # 第二步：获取音频流信息
    play_api = f"https://api.bilibili.com/x/player/playurl?bvid={bv_id}&cid={cid}&qn=0&fnver=0&fnval=16&fourk=1"
    play_resp = requests.get(play_api, headers=headers)

    if play_resp.status_code != 200:
        print(f"播放接口请求失败: {play_resp.status_code}")
        return

    play_data = play_resp.json()

    # 调试输出（正式使用时注释掉）
    print("API响应数据：", json.dumps(play_data, indent=2, ensure_ascii=False))

    if play_data.get('code') != 0:
        print(f"B站API错误: {play_data.get('message')}")
        return

    try:
        audio_url = play_data['data']['dash']['audio'][0]['baseUrl']
    except KeyError:
        print("解析音频URL失败，可能原因：\n1. 视频为大会员专属\n2. 地区限制\n3. 接口参数需要更新")
        return

    # 下载音频流（需添加Range头）
    headers.update({'Range': 'bytes=0-'})
    audio_resp = requests.get(audio_url, headers=headers, stream=True)

    # 音频处理流程
    with open("temp.m4a", 'wb') as f:
        for chunk in audio_resp.iter_content(chunk_size=1024 * 512):
            if chunk:
                f.write(chunk)

    try:
        audio = AudioSegment.from_file("temp.m4a")
        audio = audio.set_channels(1).set_frame_rate(16000)
        audio.export(
            output_path,
            format="wav",
            codec="pcm_s16le",
            bitrate="16k"
        )
        print(f"转换成功 ➜ {output_path}")
    except Exception as e:
        print(f"音频处理失败: {str(e)}")
    finally:
        import os
        if os.path.exists("temp.m4a"):
            os.remove("temp.m4a")


if __name__ == "__main__":
    download_bilibili_wav("BV19M411G7wg", "output.wav")